home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GFX Sensations 1
/
Graphic Sensations - Volume 1.iso
/
tools
/
amiga
/
3d_tools
/
t3dsrc.lha
/
writemif.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-20
|
7KB
|
227 lines
/* writemif.c - routines to output FrameMaker MIF format
* - using TTDDDLIB by Glenn M. Lewis - 7/24/91
*/
static char rcs_id[] = "$Id: writemif.c,v 1.9 1993/01/30 12:55:49 glewis Exp $";
#include <stdio.h>
#include "t3dlib.h"
#ifdef __STDC__
#include <stdlib.h>
#include <strings.h>
#include "writemif_protos.h"
#endif
/* double XSIZE = 8.5; - in the PostScript module */
/* double YSIZE = 11.0; - in the PostScript module */
#define MARGIN (0.25) /* On each side of the page */
#define PPI (72.0)
#define COS60 (0.5)
#define COS30 (0.8660)
static void write_MIF_header();
static void draw_MIF_view();
static void render_MIF_object();
static FILE *out;
static WORLD *world;
static MBB mbb;
static double xsize, ysize;
static int view;
static double xoffset, yoffset, scale, ybottom;
static int tab;
static void dotab() { register int i=tab; while (i--) fputc(' ',out); }
#define TAB(a) {dotab();fputs(a,out);}
#define TABr(a) {dotab();fputs(a,out);tab++;}
#define TABl(a) {tab--;dotab();fputs(a,out);}
#define PTAB dotab();fprintf
int write_MIF(object, file, selected_view)
WORLD *object;
FILE *file;
int selected_view;
{
double llx, lly;
register OBJECT *obj;
if (!(out = file)) return(0); /* File not open */
if (!(world = object)) return(0); /* No object */
/* Determine the extent of the world object */
mbb.minx = mbb.miny = mbb.minz = 1.0e10;
mbb.maxx = mbb.maxy = mbb.maxz = -1.0e10;
for (obj=world->object; obj; obj=obj->next) {
calculate_MBB(obj);
if (!obj->user) continue;
if (((MBB*)obj->user)->minx<mbb.minx) mbb.minx = ((MBB*)obj->user)->minx;
if (((MBB*)obj->user)->miny<mbb.miny) mbb.miny = ((MBB*)obj->user)->miny;
if (((MBB*)obj->user)->minz<mbb.minz) mbb.minz = ((MBB*)obj->user)->minz;
if (((MBB*)obj->user)->maxx>mbb.maxx) mbb.maxx = ((MBB*)obj->user)->maxx;
if (((MBB*)obj->user)->maxy>mbb.maxy) mbb.maxy = ((MBB*)obj->user)->maxy;
if (((MBB*)obj->user)->maxz>mbb.maxz) mbb.maxz = ((MBB*)obj->user)->maxz;
}
#ifdef DEBUG
fprintf(stderr, "MBB: (%.12g,%.12g,%.12g)-(%.12g,%.12g,%.12g)\n",
mbb.minx, mbb.miny, mbb.minz,
mbb.maxx, mbb.maxy, mbb.maxz);
#endif
write_MIF_header();
if (selected_view==VIEW_ALL_FOUR) {
for (view=0; view<4; view++) {
llx = ((view&0x02) ? XSIZE/2.0 : MARGIN) * PPI;
lly = ((view&0x01) ? YSIZE/2.0 : MARGIN) * PPI;
xsize = PPI*(XSIZE/2.0 - MARGIN);
ysize = PPI*(YSIZE/2.0 - MARGIN);
TABr("<Frame\n");
TAB("<Pen 0>\n");
TAB("<Fill 15>\n");
TAB("<PenWidth 0.1 pt>\n");
TAB("<Separation 0>\n");
PTAB(out, "<BRect %.12g %.12g %.12g %.12g>\n", llx, lly, xsize, ysize);
draw_MIF_view();
TABl("> # end of Frame\n");
}
} else {
xsize = PPI*(XSIZE - 2.0*MARGIN);
ysize = PPI*(YSIZE - 2.0*MARGIN);
view=selected_view;
TABr("<Frame\n");
TAB("<Pen 0>\n");
TAB("<Fill 15>\n");
TAB("<PenWidth 0.1 pt>\n");
TAB("<Separation 0>\n");
PTAB(out, "<BRect %.12g %.12g %.12g %.12g>\n", PPI*MARGIN, PPI*MARGIN, xsize, ysize);
draw_MIF_view();
TABl("> # end of Frame\n");
}
return(1);
}
static void write_MIF_header()
{
tab=0;
fputs("<MIFFile 2.00>\t# Created by TTDDDLIB by Glenn M. Lewis\n", out);
fprintf(out, "# %s\n", rcs_id);
fputs("\n<Document\n <DPageRounding DeleteEmptyPages>\n", out);
fputs(" <DSmartQuotesOn Yes>\n <DBordersOn Yes>\n <DGridOn Yes>\n", out);
fputs(" <DRulersOn Yes>\n <DSymbolsOn No>\n> # end of Document\n", out);
fputs("<Units Upt>\n", out);
}
static void draw_MIF_view()
{
double xratio, yratio, zratio, ratio;
OBJECT *obj;
if (mbb.maxx-mbb.minx>0.0) xratio=1.0/(mbb.maxx-mbb.minx); else xratio=1.0;
if (mbb.maxy-mbb.miny>0.0) yratio=1.0/(mbb.maxy-mbb.miny); else yratio=1.0;
if (mbb.maxz-mbb.minz>0.0) zratio=1.0/(mbb.maxz-mbb.minz); else zratio=1.0;
ratio = (xratio < yratio ? xratio : yratio); /* Get minimum ratio */
ratio = (ratio < zratio ? ratio : zratio);
scale = (xsize < ysize ? xsize : ysize)*ratio; /* Keep aspect ratio same */
switch(view) {
case VIEW_TOP:
xoffset = (xsize-scale/xratio)/2.0;
yoffset = (ysize-scale/yratio)/2.0;
break;
case VIEW_FRONT:
xoffset = (xsize-scale/xratio)/2.0;
yoffset = (ysize-scale/zratio)/2.0;
break;
case VIEW_ISO:
xratio = (mbb.maxx-mbb.minx)*COS30+(mbb.maxy-mbb.miny)*COS30;
if (xratio>0.0) xratio = 1.0/xratio; else xratio=1.0;
ybottom = -(mbb.maxx-mbb.minx)*COS60;
yratio = (mbb.maxz-mbb.minz)+(mbb.maxy-mbb.miny)*COS60 /* Top */
- ybottom;
if (yratio>0.0) yratio = 1.0/yratio; else yratio=1.0;
ratio = (xratio < yratio ? xratio : yratio);
scale = (xsize < ysize ? xsize : ysize)*ratio;
xoffset = (xsize-scale/xratio)/2.0;
yoffset = (ysize-scale/yratio)/2.0;
break;
case VIEW_RIGHT:
xoffset = (xsize-scale/yratio)/2.0;
yoffset = (ysize-scale/zratio)/2.0;
break;
}
for (obj=world->object; obj; obj=obj->next)
render_MIF_object(obj);
}
static void render_MIF_object(obj)
register OBJECT *obj;
{
register UWORD *f;
register OBJECT *op;
register int i, j;
int p[3];
double x[3], y[3];
if (!obj->desc) return;
for (op=obj->child; op; op=op->next) /* render children first */
render_MIF_object(op);
/* Now, the meat... */
#if 0
if (obj->desc->shap && obj->desc->shap[1]!=0) return; /* A lamp */
#endif
if (!obj->desc->edge || !obj->desc->pnts || !obj->desc->face) return;
for (f=obj->desc->face,i=obj->desc->fcount; i--; f+=3) {
p[0] = obj->desc->edge[((*f)<<1)];
p[1] = obj->desc->edge[((*f)<<1)+1];
if (obj->desc->edge[((f[1])<<1)] == p[0] ||
obj->desc->edge[((f[1])<<1)] == p[1])
p[2] = obj->desc->edge[((f[1])<<1)+1];
else
p[2] = obj->desc->edge[((f[1])<<1)];
switch(view) {
case VIEW_TOP:
for (j=3; j--; ) {
x[j] = obj->desc->pnts[p[j]].x-mbb.minx;
y[j] = obj->desc->pnts[p[j]].y-mbb.miny;
}
break;
case VIEW_FRONT:
for (j=3; j--; ) {
x[j] = obj->desc->pnts[p[j]].x-mbb.minx;
y[j] = obj->desc->pnts[p[j]].z-mbb.minz;
}
break;
case VIEW_ISO:
for (j=3; j--; ) {
x[j] = (obj->desc->pnts[p[j]].x-mbb.minx)*COS30
+(obj->desc->pnts[p[j]].y-mbb.miny)*COS30;
y[j] = (obj->desc->pnts[p[j]].z-mbb.minz)
-(obj->desc->pnts[p[j]].x-mbb.minx)*COS60
+(obj->desc->pnts[p[j]].y-mbb.miny)*COS60
- ybottom;
}
break;
case VIEW_RIGHT:
for (j=3; j--; ) {
x[j] = obj->desc->pnts[p[j]].y-mbb.miny;
y[j] = obj->desc->pnts[p[j]].z-mbb.minz;
}
break;
}
if (x[0]==x[1] && x[1]==x[2] && y[0]==y[1] && y[1]==y[2]) continue;
TABr("<Polygon\n");
PTAB(out, "<Point %0.2lf %0.2lf>\n", xoffset+scale*x[0],
ysize-(yoffset+scale*y[0]));
if (!(x[0]==x[1] && y[0]==y[1])) {
PTAB(out, "<Point %0.2lf %0.2lf>\n", xoffset+scale*x[1],
ysize-(yoffset+scale*y[1]));
}
if (!(x[0]==x[2] && y[0]==y[2]) && !(x[1]==x[2] && y[1]==y[2])) {
PTAB(out, "<Point %0.2lf %0.2lf>\n", xoffset+scale*x[2],
ysize-(yoffset+scale*y[2]));
}
TABl(">\n");
}
}